import MemoryBlock from './MemoryBlock'

//内存管理器
class MemoryManager {
  constructor(totalMemory) {
    this.totalMemory = totalMemory
    // 内存块
    this.memoryBlocks = [new MemoryBlock(0, totalMemory)]
    // 进程计数器（进程ID）
    this.processCounter = 1
    // 已分配的进程
    this.allocatedProcesses = []
  }

  // 最先适应算法
  firstFitAllocate(processSize) {
    for (let i = 0; i < this.memoryBlocks.length; i++) {
      const block = this.memoryBlocks[i]
      // 不为空闲块且大小足够
      if (!block.processId && block.size >= processSize) {
        const startAddress = block.start

        // 直接分配
        if (block.size === processSize) {
          block.processId = this.processCounter
        } else {
          // 分为两块，一块分配给进程，一块变成空闲区
          const newBlock = new MemoryBlock(
            block.start + processSize,
            block.size - processSize
          )
          block.size = processSize
          block.processId = this.processCounter

          // 在进程后面插入新的空闲块
          this.memoryBlocks.splice(i + 1, 0, newBlock)
        }

        // 记录分配的进程
        this.allocatedProcesses.push({
          id: this.processCounter,
          size: processSize,
          startAddress: startAddress
        })

        this.processCounter++
        return startAddress
      }
    }

    // 内存不足，无法分配
    return -1
  }

  // 最佳适应算法（按块大小递增）
  bestFitAllocate(processSize) {
    return this._allocateMemory(
      processSize,
      (a, b) => a.block.size - b.block.size
    )
  }

  // 最坏适应算法（按块大小递减）
  worstFitAllocate(processSize) {
    return this._allocateMemory(
      processSize,
      (a, b) => b.block.size - a.block.size
    )
  }

  // 释放进程
  releaseProcess(processId) {
    const processIndex = this.allocatedProcesses.findIndex(
      (p) => p.id === processId
    )
    if (processIndex !== -1) {
      const blockIndex = this.memoryBlocks.findIndex(
        (block) => block.processId === processId
      )

      if (blockIndex !== -1) {
        this.memoryBlocks[blockIndex].processId = null
        this.mergeAdjacentFreeBlocks()
      }

      this.allocatedProcesses.splice(processIndex, 1)
    }
  }

  // 合并相邻的空闲块
  mergeAdjacentFreeBlocks() {
    for (let i = 0; i < this.memoryBlocks.length - 1; i++) {
      if (
        !this.memoryBlocks[i].processId &&
        !this.memoryBlocks[i + 1].processId
      ) {
        this.memoryBlocks[i].size += this.memoryBlocks[i + 1].size
        this.memoryBlocks.splice(i + 1, 1)
        i--
      }
    }
  }

  // 获取进程的颜色
  getProcessColor(processId) {
    if (!this.processColors) {
      this.processColors = {}
    }
    if (!this.processColors[processId]) {
      const r = Math.floor(Math.random() * 200)
      const g = Math.floor(Math.random() * 200)
      const b = Math.floor(Math.random() * 200)
      this.processColors[processId] = `rgba(${r},${g},${b}, 0.5)`
    }
    return this.processColors[processId]
  }

  // 通用内存分配方法（最佳分配法和最坏分配法共用）
  _allocateMemory(processSize, compareFn) {
    // 创建按指定规则排序的临时数组
    const sortedBlocks = this.memoryBlocks
      .map((block, index) => ({ block, index }))
      .filter((item) => !item.block.processId && item.block.size >= processSize)
      .sort(compareFn)

    // 选择第一个符合要求的块
    if (sortedBlocks.length > 0) {
      const { block, index: blockIndex } = sortedBlocks[0]
      const startAddress = block.start

      if (block.size === processSize) {
        block.processId = this.processCounter
      } else {
        const newBlock = new MemoryBlock(
          block.start + processSize,
          block.size - processSize
        )
        block.size = processSize
        block.processId = this.processCounter
        this.memoryBlocks.splice(blockIndex + 1, 0, newBlock)
      }

      this.allocatedProcesses.push({
        id: this.processCounter,
        size: processSize,
        startAddress: startAddress
      })

      this.processCounter++
      return startAddress
    }
    return -1
  }
}

// 导出 MemoryManager 类
export default MemoryManager
